#include <QPrintDialog>
#include <QPainter>
#include <QTextCursor>
#include "CPrintTest.h"
#include <QTextEdit>
#include <QTextTable>
#include <QPrintPreviewDialog>
#include "CTest.h"

CPrintTest::CPrintTest(QWidget *parent) : QObject(parent)
{
    this->parent = parent;
    printer = new QPrinter;
}

CPrintTest::~CPrintTest()
{

}

void CPrintTest::printTest(CTest &test, CPrintSettings &printSettings)
{
    QPrintDialog printDialog(printSettings.getPageSettings(), parent);
    if (printDialog.exec())
    {
        QTextDocument *textDoc = 0;
        textDoc = new QTextDocument;
	QTextCursor cursor(textDoc);
	QTextDocument *tmpDoc = 0;
        tmpDoc = new QTextDocument();
	for (int i=0; i<test.getListQuestion().count(); i++)
	{
	    questionToTextDocument(tmpDoc, test.getListQuestion().getQuestion(i));
            cursor.insertHtml(QObject::tr("<p style=\" margin-top:5px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Вопрос №") +
			      QVariant(i+1).toString()+ "</p>" + tmpDoc->toHtml()+"<br>");
	}
	_printTest(textDoc, printDialog.printer(), printSettings);
//	textDoc->print(printer);
        if (tmpDoc != 0) delete tmpDoc;
        if (textDoc != 0) delete textDoc;
    }
}

void CPrintTest::printPreviewTest (CTest &test, CPrintSettings &printSettings)
{
#ifndef QT_NO_PRINTER
    this->test = test;
    this->printSettings = printSettings;
    QPrintPreviewDialog preview(static_cast<QPrinter*>(printSettings.getPageSettings()), parent);
    preview.setWindowFlags (Qt::Window);
    connect(&preview, SIGNAL(paintRequested(QPrinter *)), SLOT(printPreview(QPrinter *)));
    preview.exec();
#endif
}

void CPrintTest::printPreview(QPrinter *printer)
{
#ifndef QT_NO_PRINTER
    QTextDocument *textDoc = 0;
    textDoc = new QTextDocument;
    QTextCursor cursor(textDoc);
    QTextDocument *tmpDoc = 0;
    tmpDoc = new QTextDocument();
    for (int i=0; i<test.getListQuestion().count(); i++)
    {
	questionToTextDocument(tmpDoc, test.getListQuestion().getQuestion(i));
	cursor.insertHtml(QObject::tr("<p style=\" margin-top:5px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Вопрос №") +
			  QVariant(i+1).toString()+ "</p>" + tmpDoc->toHtml()+"<br>");
    }
    _printTest(textDoc, printer, printSettings);
#endif
}

void CPrintTest::_printTest(QTextDocument *textDoc, QPrinter *printer, CPrintSettings &printSettings)
{
    //Задаем параметры страницы
    qreal top, right, bottom, left;
    printSettings.getPageSettings()->getPageMargins(&left, &top, &right, &bottom, CPageSettings::Millimeter);
    printer->setPageMargins(left, top, right, bottom, CPageSettings::Millimeter);
    printer->setOrientation(printSettings.getPageSettings()->orientation());
    printer->setPaperSize(printSettings.getPageSettings()->paperSize());

    QTextDocument *pagination = 0;
    QSizeF size(0,0);
    printer->setFullPage(false);

    int x1 = QVariant(printer->pageRect().width()).toDouble() * CPagination::leftIndent;
    int y1 = QVariant(printer->pageRect().height()).toDouble() * CPagination::topIndent;
    int x2 = QVariant(printer->pageRect().width()).toDouble() - QVariant(printer->pageRect().width()).toDouble() * CPagination::rightIndent;
    int y2 = QVariant(printer->pageRect().height()).toDouble() - QVariant(printer->pageRect().height()).toDouble() * CPagination::bottomIndent;

    QString paginationHtml;
    QRect printerRect(0,0,x2-x1,y2);
//    qDebug()<<x1<<y1<<x2<<y2;
    //Делаем настройки включения нумерации, если pagination == true
    if (printSettings.getPagination().isPagination())
    {
	//Формируем html-строку в которую будут подставлятся align (%1) и номер страницы (%2)
	paginationHtml = "<p align=\"%1\" style=\" margin=0;\">%2</p>";
	//Вставляем выравнивание
	switch (printSettings.getPagination().getAlignment())
	{
	case (CPagination::center):
	    paginationHtml = paginationHtml.arg("center");
	    break;
	case (CPagination::right):
	    paginationHtml = paginationHtml.arg("right");
	    break;
	case (CPagination::left):
	    paginationHtml = paginationHtml.arg("left");
	    break;
	}

	pagination = new QTextDocument();
	//pagination->setHtml(paginationHtml);
	pagination->setPageSize(printerRect.size());
	size = pagination->size();
    }
    //Calculating the main document size for one page
    QSizeF center_size(printerRect.width(), (printerRect.height() - size.toSize().height()));

    textDoc->setPageSize(center_size);
//    qDebug()<<printerRect.width()<<printerRect.height()<<textDoc->size().toSize()<<center_size;

    ///Setting up the rectangles for each section.
    QRect paginationRect = QRect(QPoint(0,0), size.toSize());
    QRect contentRect = QRect(QPoint(0,0), textDoc->size().toSize());    /// Main content rectangle.
    QRect currentRect = QRect(QPoint(0,0), center_size.toSize());        /// Current main content rectangle.

    QPainter painter(printer);

    QString tmpHtml = paginationHtml;

    int i = 0;
    while (currentRect.intersects(contentRect))
    {///Loop if the current content rectangle intersects with the main content rectangle.
	i++;
	///Resetting the painter matrix coordinate system.
	painter.resetMatrix();
	///Applying negative translation of painter coordinate system by current main content rectangle top y coordinate.
	painter.translate(x1, -currentRect.y());
	///Applying positive translation of painter coordinate system by header hight.
	painter.translate(0, paginationRect.height());
	///Drawing the center content for current page.
	textDoc->drawContents(&painter, currentRect);
	///Resetting the painter matrix co ordinate system.
	painter.resetMatrix();
	if (printSettings.getPagination().isPagination())
	{
	    if (printSettings.getPagination().getFirstPageNumbered() || (i>1))
	    {
		tmpHtml = tmpHtml.arg(QVariant(printSettings.getPagination().getStartPage()+i-1).toString());
	    }
	    else
		tmpHtml = tmpHtml.arg("");
	    pagination->clear();
	    pagination->setHtml(tmpHtml);
	    ///Drawing the header on the top of the page
	    if (printSettings.getPagination().getLocation() == CPagination::top)
	    {
		pagination->drawContents(&painter, paginationRect);
	    }
	    else
	    {
		///Applying positive translation of painter co-ordinate system to draw the footer
		painter.translate(x1, paginationRect.height());
		painter.translate(0, center_size.height());
		pagination->drawContents(&painter, paginationRect);
	    }
	    tmpHtml = paginationHtml;
	}

	///Translating the current rectangle to the area to be printed for the next page
	currentRect.translate(0, currentRect.height());
	///Inserting a new page if there is till area left to be printed
	if (currentRect.intersects(contentRect))
	{
	    printer->newPage();
	}
    }
    if (pagination) delete pagination;
}

//Метод сливает вопрос с ответами в один документ
void CPrintTest::questionToTextDocument(QTextDocument * textDoc, const CQuestion &question)
{
    QTextCursor cursor(textDoc);
    textDoc->clear();
    cursor.insertHtml(question.getTextQuestion());
    if (question.getListAnswer().count()==0)
    {
        return;
    }
    cursor.insertList(QTextListFormat::ListLowerAlpha);
    for (int i=0; i<question.getListAnswer().count(); i++)
    {
        //получаем абзацы текущего ответа
        QStringList text = question.getListAnswer().getAnswer(i).getTextAnswer().split(QRegExp("</{0,1}p[^>]*>"),
                                                                                           QString::SkipEmptyParts);
        //если в ответе абзацы есть, то сливаем их все в список
        if (!text.empty())
        {
            for (int j=1; j<text.count()-1; j+=2)
            {
                cursor.insertHtml(text[j]);
                if (j != text.count()-2) cursor.insertHtml("<br>");
            }
            if (i != question.getListAnswer().count()-1) cursor.insertBlock(); //чтобы не вставлять лишний блок в конце
        }
    }
    cursor.insertBlock(QTextBlockFormat(), QTextCharFormat());
}

QTextTableFormat CPrintTest::tableFormat()
{
    QTextTableFormat tableFormat;
    tableFormat.setBorderStyle(QTextFrameFormat::BorderStyle_Solid);
    tableFormat.setBorder(0.5);
    QBrush brush;
    QColor color(0,0,0);
    brush.setColor(color);
    tableFormat.setBorderBrush(brush.color());
    tableFormat.setCellPadding(3);
    tableFormat.setCellSpacing(0);
    tableFormat.setPadding(0);
    return tableFormat;
}

void CPrintTest::printKeys(CTest &test)
{
    QPrintDialog printDialog(printer, parent);
    if (printDialog.exec())
    {
        QTextDocument *textDoc = 0;
        textDoc = new QTextDocument;
        QTextCursor cursor(textDoc);

        //настраиваем ширину столбцов
        QVector<QTextLength> width;
        QTextLength t1(QTextLength::FixedLength, 100);
        QTextLength t2(QTextLength::FixedLength, printer->paperSize(QPrinter::Point).width()-100);
        width.push_back(t1);
        width.push_back(t2);
        QTextTableFormat tableFormat = this->tableFormat();
        tableFormat.setColumnWidthConstraints(width);

        //вставка таблицы
        QTextTable *table = cursor.insertTable(test.getListQuestion().count()+1, 2, tableFormat);
        cursor = table->cellAt(0,0).firstCursorPosition();
        cursor.insertHtml(QObject::tr("№ п/п"));
        cursor = table->cellAt(0,1).firstCursorPosition();
        cursor.insertHtml(QObject::tr("Ответы"));
        //Вывод ответов
        for (int i=0; i<test.getListQuestion().count(); i++)
        {
            cursor = table->cellAt(i+1,0).firstCursorPosition();
            cursor.insertHtml(QVariant(i+1).toString());
            cursor = table->cellAt(i+1,1).firstCursorPosition();
            for (int j=0; j<test.getListQuestion().getQuestion(i).getListAnswer().count(); j++)
            {
                if (test.getListQuestion().getQuestion(i).getListAnswer().getAnswer(j).isRightAnswer())
                    cursor.insertHtml(QVariant(j+1).toString() + " ");
            }
        }
        textDoc->print(printer);
        if (textDoc) delete textDoc;
    }
}

void CPrintTest::printComment(CTest &test)
{
    QPrintDialog printDialog(printer, parent);
    if (printDialog.exec())
    {
        QTextDocument *textDoc = 0;
        textDoc = new QTextDocument;
        QTextCursor cursor(textDoc);

        //настраиваем ширину столбцов
        QVector<QTextLength> width;
        QTextLength t1(QTextLength::FixedLength, 100);
        QTextLength t2(QTextLength::FixedLength, printer->paperSize(QPrinter::Point).width()-100);
        width.push_back(t1);
        width.push_back(t2);
        QTextTableFormat tableFormat = this->tableFormat();
        tableFormat.setColumnWidthConstraints(width);

        //вставка таблицы
        QTextTable *table = cursor.insertTable(test.getListQuestion().count()+1, 2, tableFormat);
        cursor = table->cellAt(0,0).firstCursorPosition();
        cursor.insertHtml(QObject::tr("№ п/п"));
        cursor = table->cellAt(0,1).firstCursorPosition();
        cursor.insertHtml(QObject::tr("Комментарий"));
        //Вывод комментов
        for (int i=0; i<test.getListQuestion().count(); i++)
        {
            cursor = table->cellAt(i+1,0).firstCursorPosition();
            cursor.insertHtml(QVariant(i+1).toString());
            cursor = table->cellAt(i+1,1).firstCursorPosition();
            cursor.insertHtml(test.getListQuestion().getQuestion(i).getComment());
        }
        textDoc->print(printer);
        if (textDoc) delete textDoc;
    }
}
